package com.bluesky.jwf.component.window;

import java.util.ArrayList;
import java.util.List;

import com.bluesky.javawebbrowser.domain.html.tags.Div;

/**
 * it is the 'screen' window behind any window. normally a screen window has no
 * border. all of its area is used for child window. and if there is dialog
 * window, a mask layer will be placed behind the dialog.
 * 
 * @author hz00260
 * 
 */
public class ScreenWindow extends Window {

	/**
	 * by pixel(px)
	 */
	private int physicalWidth;
	private int physicalHeight;
	/*
	 * the mask layer is used to mask anything except the dialog up front.
	 */
	private Div maskLayer;

	@Override
	public void init(String html) {

		super.init(html);

		// screen window is headless.
		head.detach();
		// clear body stuff
		bodyTag.removeAllChildren();

		// add a mask div layer
		/*
		 * <div id="c" class="transparent_class" style="background-color:;
		 * border:1px solid black; width:100%; height:100%; position: absolute;
		 * display:block;z-index:3; ">div b</div>
		 */
		maskLayer = new Div();
		maskLayer.setAttribute("class", "mask-layer opacity-50");
		maskLayer.setStyleAttribute("z-index", "-1");

		windowTag.addChild(maskLayer);
	}

	/**
	 * notify all windows that they are going to be rendered. it will fire the
	 * Window.onShow() event.
	 */
	public void notifyWindowsOfRender() {

		List<Window> allWindows = new ArrayList<Window>();

		getAllWindows(allWindows);
		int last = allWindows.size();
		int cur;
		while (true) {
			// notify every window
			for (Window w : allWindows)
				w.onRender();

			allWindows.clear();
			getAllWindows(allWindows);
			cur = allWindows.size();

			// if the window amount is same, no need to repeat.
			if (cur == last)
				break;

			last = cur;
		}

	}

	@Override
	public void addChildWindow(Window child) {

		super.addChildWindow(child);
		bodyTag.addChild(child);

		calcWindows();
		/**
		 * place the child into the child window area. here only the most front
		 * window showed.
		 */
		// removeAllChildren();
		// Window mostFont = getMostFrontChildWindow();
		// addChild(mostFont);
	}

	@Override
	public void removeChildWindow(Window child) {

		super.removeChildWindow(child);
		bodyTag.removeChild(child);

		calcWindows();
		// removeAllChildren();
		// Window mostFont = getMostFrontChildWindow();
		// if (mostFont != null)
		// addChild(mostFont);
	}

	/*
	 * re-calculate the window position and z-order
	 */
	protected void calcWindows() {
		for (int i = 0; i < childrenWindow.size(); i++) {
			Window w = childrenWindow.get(i);

			// only for Dialog, window ignored.
			if (w instanceof Dialog) {

				int windowWidth = calcLength(w.getWidth(), physicalWidth);
				int windowHeight = calcLength(w.getHeight(), physicalHeight);

				int left = physicalWidth / 2 - windowWidth / 2;
				int top = physicalHeight / 2 - windowHeight / 2;

				// default is 30%.
				if (left < 0)
					left = physicalWidth / 3;
				if (top < 0)
					top = physicalHeight / 3;

				w.setLeft(String.format("%dpx", left));
				w.setTop(String.format("%dpx", top));

			}
			w.setZOrder(i * 10);

		}

		// mask is under the top window
		int z = (childrenWindow.size() - 1) * 10 - 1;

		if (childrenWindow.size() == 1)
			maskLayer.setStyleAttribute("display", "none");
		else
			maskLayer.removeStyleAttribute("display");

		maskLayer.setStyleAttribute("z-index", String.valueOf(z));

	}

	/**
	 * only support 'px' and '%'.
	 * 
	 * @param exp
	 * @param totalLength
	 * @return
	 */
	private int calcLength(String exp, int totalLength) {
		if (exp == null || exp.isEmpty())
			return totalLength / 3;

		int length = -1;
		if (exp.endsWith("%")) {
			int percent = Integer.valueOf(exp.replace("%", ""));
			length = percent / 100 * totalLength;
		} else if (exp.endsWith("px")) {
			length = Integer.valueOf(exp.replace("px", ""));
		} else
			throw new RuntimeException("unknow expression:" + exp);
		return length;
	}

	public int getPhysicalWidth() {
		return physicalWidth;
	}

	public void setPhysicalWidth(int physicalWidth) {
		this.physicalWidth = physicalWidth;
	}

	public int getPhysicalHeight() {
		return physicalHeight;
	}

	public void setPhysicalHeight(int physicalHeight) {
		this.physicalHeight = physicalHeight;
	}

	/*
	 * the main window is always the first child
	 */
	public MainWindow getMainWindow() {
		if (!getChildrenWindow().isEmpty()) {
			Window w = getChildrenWindow().get(0);
			if (w instanceof MainWindow)
				return (MainWindow) w;
		}

		return null;
	}

	@Override
	public String getTitle() {
		MainWindow mw = getMainWindow();
		if (mw != null)
			return mw.getTitle();
		else
			return "";
	}

	public static void main(String[] args) {
		Float.valueOf("10%");
	}
}
